home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / NextAnswers / 1437_multiple_declarations_for_method_setName.rtf < prev    next >
Text File  |  1993-11-08  |  4KB  |  81 lines

  1. {\rtf0\ansi{\fonttbl\f0\fnil Times-Roman;\f1\fmodern Courier;\f2\fswiss Helvetica;\f3\fmodern Ohlfs;}
  2. \paperw11940
  3. \paperh10080
  4. \margl120
  5. \margr1000
  6. {\colortbl;\red0\green0\blue0;}
  7. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f0\b0\i0\ulnone\fs28\fc0\cf0 Q:  I need to use the method 
  8. \b setName: 
  9. \b0 for both a Sound object and an NXImage object in the same file.  However, I always get this warning:\
  10. \
  11.      
  12. \f1\fs24\fc1\cf1 warning: multiple declarations for method `setName:'
  13. \f0\fs28  \
  14. \
  15. at compilation time.  In addition, occasionally the wrong method is called at run-time.  How can I get rid of the warning and make sure the correct method is always used?\
  16. \
  17. A:  The problem is caused by the fact that NXImage's 
  18. \b setName:
  19. \b0  method returns a BOOLEAN, while Sound's 
  20. \b setName:
  21. \b0  returns an 
  22. \b id
  23. \b0 .  You can avoid the problem by using static typing, instead of declaring the objects to be of type 
  24. \b id
  25. \b0 .  Static typing enables the compiler to do better type checking. The following code snippet shows how to do it:\
  26. \
  27.  
  28. \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f1\fs24\fc1\cf1     Sound *mySound;        /* not: id mySound */\
  29.     NXImage *myImage;    /* not: id myImage */\
  30.     \
  31.     mySound = [[Sound alloc] init];\
  32.     myImage = [[NXImage alloc] init];\
  33.     [mySound setName:"The Beatles"];\
  34.     [myImage setName:"The Stars"];\
  35. \
  36.  
  37. \pard\tx740\tx1500\tx2260\tx3020\tx3780\tx4520\tx5280\tx6040\tx6800\tx7560\f0\fs28\fc1\cf1 If static typing is not possible, you can use type-casting instead:\
  38.  
  39. \f2\fs24 \
  40.  
  41. \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f1\fc1\cf1     id mySound, myImage;\
  42.     \
  43.     mySound = [[Sound alloc] init];\
  44.     myImage = [[NXImage alloc] init];\
  45.     [(Sound *)mySound setName:"The Beatles"];\
  46.     [(NXImage *)myImage setName:"The Stars"];\
  47.  
  48. \f2\i \
  49.  
  50. \f1\i0     
  51. \f0\fs28 \
  52.  
  53. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc0\cf0 Note that to prevent similar problems when using duplicate method names for different classes, you should keep their argument types and return value types identical, unless you plan on using static typing to differentiate them.\
  54. \
  55.  
  56. \fc1\cf1 Why does the compiler not do better type checking by default?  The reason is that Objective-C uses dynamic binding (also known as "run-time binding") to give you greater flexibility in deciding which object will be sent a given message.  Dynamic binding means that the class of the message's recipient is determined by the Objective-C run-time system rather than by the compiler.  This facility lets you send the same message to any of several different classes of object (each declared as type 
  57. \b id
  58. \b0 ), depending on the current state of the application.  
  59. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 A good example of the potential of dynamic binding is InterfaceBuilder, which 
  60. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 can 
  61. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 manipulate many different 
  62. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 types of
  63. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1  object
  64. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 s
  65. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 , not all of which existed when InterfaceBuilder was co
  66. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 mpil
  67. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 ed.
  68. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 \
  69. \
  70. The compiler doesn't care if several different classes use exactly the same method name, because the class of the recipient won't be determined anyway until run-time; and as long as the class implements the method, all is well.  In your problematic case, however, the compiler can't figure out which of two similar method names is being invoked by your code, and it may decide on the wrong name.  \
  71. \
  72. For more on dynamic binding and Objective-C, see ../Objective-C/why_objective-C.rtf.\
  73.  
  74. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc0\cf0 \
  75.  
  76. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 QA793\
  77. \
  78. Valid for 2.0, 3.0\
  79. \
  80.  
  81.